﻿
Imports System.IO
Imports xmlctrl
Imports xhtmlctrl
Imports webctrl

Public Class posterCommon
    Public Class image
        Public Const startTag As String = "[img]"
        Public Const endTag As String = "[/img]"
        Public Const defaultName As String = "image"
        Public Const defaultText As String = "insert an image"
        Public Const defaultInputTitle As String = "please input an image address."
#If RETIRED Then
        Public Const textVar As String = "pos_vit"
#End If
        Public Const inputTitleVar As String = "pos_vii"
    End Class

    Public Class url
        Public Const startTag As String = "[url]"
        Public Const endTag As String = "[/url]"
        Public Const defaultName As String = "url"
        Public Const defaultText As String = "insert a url"
        Public Const defaultInputTitle As String = "please input a url."
#If RETIRED Then
        Public Const textVar As String = "pos_vut"
#End If
        Public Const inputTitleVar As String = "pos_vui"
    End Class

    Public Class media
        Public Const startTag As String = "[mda]"
        Public Const endTag As String = "[/mda]"
        Public Const defaultName As String = "media"
        Public Const defaultText As String = "insert a media"
        Public Const defaultInputTitle As String = "please input a media address."
        Public Const inputTitleVar As String = "pos_vmi"
    End Class

    Public Class flash
        Public Const startTag As String = "[swf]"
        Public Const endTag As String = "[/swf]"
        Public Const defaultName As String = "flash"
        Public Const defaultText As String = "insert a flash"
        Public Const defaultInputTitle As String = "please input a flash address."
        Public Const inputTitleVar As String = "pos_vfi"
    End Class

    Public Class location
        Public Const startTag As String = "[location]"
        Public Const endTag As String = "[/location]"
        Public Const defaultName As String = "location"
        Public Const defaultText As String = "i am at ..."
        Public Const defaultInputTitle As String = "please input a location."
        Public Const inputTitleVar As String = "pos_vli"
    End Class

    Public Class preview
        Public Const defaultText As String = "preview"
    End Class

    Public Const defaultSupportedTagsText As String = "supported tags"
    Public Const defaultValueVar As String = "pos_vv"
    Public Const defaultValue As String = "http://"
End Class

Public Class poster
    Inherits container

    Public Const containerClassName As String = "wc_p"
    Public Const buttonsClassName As String = "bs"
    Public Const buttonClassName As String = "b"
    Public Const inputClassName As String = "i"
    Public Const inputIdBase As String = "wc_pi"
    Public Const supportedTagsClassName As String = "spt"

    Public Class datasource
        Public inputName As String = Nothing
        Public page As xhtmlpage = Nothing

        Public previewText As String = Nothing
        Public previewImage As String = Nothing
        Public previewUrl As String = Nothing

        Public supportedTagsText As String = Nothing
        Public defaultValue As String = Nothing

        Public imageName As String = Nothing
        Public imageText As String = Nothing
        Public imageImage As String = Nothing
        Public imageInputTitle As String = Nothing

        Public urlName As String = Nothing
        Public urlText As String = Nothing
        Public urlImage As String = Nothing
        Public urlInputTitle As String = Nothing

        Public mediaName As String = Nothing
        Public mediaText As String = Nothing
        Public mediaImage As String = Nothing
        Public mediaInputTitle As String = Nothing

        Public flashName As String = Nothing
        Public flashText As String = Nothing
        Public flashImage As String = Nothing
        Public flashInputTitle As String = Nothing

        Public locationName As String = Nothing
        Public locationText As String = Nothing
        Public locationImage As String = Nothing
        Public locationInputTitle As String = Nothing
    End Class

    Public Const promptFunctionName As String = "pstprm"
    Public Const previewFunctionName As String = "preview"
    Public Const previewFormVar As String = "preview_fm"

    Private Shared Sub promptRegister(ByVal inlineScript As inlineScript)
        assert(Not inlineScript Is Nothing, "inlineScript is nothing.")
        'i = id, t = title, s = startTag, e = endTag
#If RETIRED Then
        Const inputBoxResult As String = "r"
        inlineScript.addscript("posterprompt", "function " + functionName + "(i,t,s,e){" + _
                                var.invoke(inputBoxResult, _
                                    prompt.invoke(inlineScript, "t", posterCommon.defaultValueVar)) + ";" + _
                                ifelse.invoke(notnull.invoke(inlineScript, inputBoxResult), _
                                                  changeValueById.invoke(inlineScript, "i", _
                                                      getValueById.invoke(inlineScript, "i") + "+" + _
                                                                          "s+" + inputBoxResult + "+e")) + _
                                "}")
#End If
        inlineScript.addscript(promptFunctionName, _
                               "function " + promptFunctionName + "(i,t,s,e,d){" + _
                                   prompt2.invoke(inlineScript, _
                                                  "function(" + prompt2.inputBoxResult + "){" + _
                                                      changeValueById.invoke(inlineScript, "i", _
                                                          getValueById.invoke(inlineScript, "i") + _
                                                          "+" + "s+" + prompt2.inputBoxResult + "+e") + _
                                                  ";}", _
                                                  title:="t", value:="d") + _
                               "}")
    End Sub

    Private Shared Function promptInvoke(ByVal ds As datasource, _
                                         ByVal inputTitle As String, _
                                         ByVal startTag As String, ByVal endTag As String, _
                                         ByVal id As String, _
                                         ByVal needDefaultVar As Boolean, _
                                         Optional ByRef actionTarget As String = Nothing) As String
        assert(Not ds Is Nothing, "ds is nothing.")
        assert(Not isemptystring(inputTitle), "inputTitle is empty string.")
        If Not ds.page Is Nothing AndAlso Not ds.page.inlineScript() Is Nothing Then
            promptRegister(ds.page.inlineScript())
        End If
        actionTarget += promptFunctionName + "('" + id + "'," + inputTitle + ",'" + startTag + "','" + endTag + "'," + _
                                               ifoper(needDefaultVar, posterCommon.defaultValueVar, "''") + ")"
        Return actionTarget
    End Function

    Private Shared sub previewRegister(ByVal inlineScript As inlineScript)
        assert(Not inlineScript Is Nothing)
        inlineScript.addscript(previewFormVar, var.invoke(previewFormVar) + ";")
        inlineScript.addscript(previewFunctionName, _
                               "function " + previewFunctionName + "(u,t,i){" + _
                               "var f;" + _
                               ifelse.invoke(null.invoke(inlineScript, previewFormVar), _
                                             "f=" + createElement.invoke(inlineScript, """form""") + ";" + _
                                             previewFormVar + "=f;" + _
                                             "f.action=u;" + _
                                             "f.target=""_blank"";" + _
                                             "f.method=""post"";" + _
                                             display.invoke(inlineScript, "f", """none""") + ";" + _
                                             appendChild.invoke(inlineScript, _
                                                                document.name(inlineScript) + ".body", _
                                                                "f"), _
                                             "f=" + previewFormVar) + _
                               "f.innerHTML=""<textarea name=""+t+"">""+" + _
                                            getValueById.invoke(inlineScript, "i") + _
                                            "+""</textarea>"";" + _
                               ifoper(isdebugmode(), newline.incode(), emptyString) + _
                               "f.submit();" + _
                               "return " + [true].name(inlineScript) + ";}")
    End Sub

    Private Shared Function previewInvoke(ByVal ds As datasource, _
                                          ByVal inputId As String, _
                                          Optional ByRef actionTarget As String = Nothing) As String
        assert(Not ds Is Nothing)
        assert(Not isemptystring(inputId))
        If Not ds.page Is Nothing AndAlso Not ds.page.inlineScript() Is Nothing Then
            previewRegister(ds.page.inlineScript())
        End If

        actionTarget += previewFunctionName + "('" + ds.previewUrl + "','" + ds.inputName + "','" + inputId + "')"
        Return actionTarget
    End Function

    Private Shared Sub setButtonAppearance(ByVal root As button, _
                                           ByVal image As String, ByVal text As String, ByVal defaultText As String)
        assert(Not root Is Nothing)
        If Not isemptystring(image) Then
            Dim img As img = Nothing
            img = New img()
            img.src = image
            If isemptystring(text) Then
                img.alt = defaultText
                img.title = defaultText
            End If
            root.addchild(img)
        End If
        'at least add something to this button
        If Not isemptystring(text) OrElse isemptystring(image) Then
            Dim xmltext As xmltext = Nothing
            xmltext = New xmltext()
            xmltext.text = ifoper(isemptystring(text), defaultText, text)
            root.addchild(xmltext)
        End If
        root.type = xhtmlctrl.button.type_enum.button
        root.class = buttonClassName
    End Sub

    Private Shared Function createButton(ByVal image As String, ByVal text As String, ByVal defaultText As String, _
                                         ByVal ds As datasource, _
                                         ByVal inputTitle As String, _
                                         ByVal startTag As String, ByVal endTag As String, _
                                         ByVal inputId As String, _
                                         Optional ByVal needDefaultValue As Boolean = True) As xhtmlControl
        Dim button As button = Nothing
        button = New button()
        setButtonAppearance(button, image, text, defaultText)
        button.onclick = promptInvoke(ds, inputTitle, startTag, endTag, inputId, needDefaultValue)

        Return button
    End Function

    Private Shared Sub stringRegisterImpl(ByVal ds As datasource, ByVal scriptName As String, _
                                          ByVal varName As String, ByVal text As String, ByVal defaultText As String)
        assert(Not ds Is Nothing, "ds is nothing.")
        assert(Not ds.page Is Nothing, "ds.page is nothing.")
        assert(Not ds.page.inlineScript() Is Nothing, "ds.page.inlineScript() is nothing.")

        ds.page.inlineScript().addscript(scriptName, _
                                         var.invoke(varName, "'" + ifoper(isemptystring(text), _
                                                                          defaultText, text) + "';"))
    End Sub

    Private Shared Sub stringRegister(ByVal ds As datasource)
#If RETIRED Then
        stringRegisterImpl(ds, "posterStringRegister_imageText", _
                           posterCommon.image.textVar, ds.imageText, posterCommon.image.defaultText)
#End If
        stringRegisterImpl(ds, "posterStringRegister_imageInputTitle", _
                           posterCommon.image.inputTitleVar, ds.imageInputTitle, posterCommon.image.defaultInputTitle)
#If RETIRED Then
        stringRegisterImpl(ds, "posterStringRegister_urlText", _
                           posterCommon.url.textVar, ds.urlText, posterCommon.url.defaultText)
#End If
        stringRegisterImpl(ds, "posterStringRegister_urlInputTitle", _
                           posterCommon.url.inputTitleVar, ds.urlInputTitle, posterCommon.url.defaultInputTitle)
        stringRegisterImpl(ds, "posterStringRegister_mediaInputTitle", _
                           posterCommon.media.inputTitleVar, ds.mediaInputTitle, posterCommon.media.defaultInputTitle)
        stringRegisterImpl(ds, "posterStringRegister_flashInputTitle", _
                           posterCommon.flash.inputTitleVar, ds.flashInputTitle, posterCommon.flash.defaultInputTitle)
        stringRegisterImpl(ds, "posterStringRegister_locationInputTitle", _
                           posterCommon.location.inputTitleVar, ds.locationInputTitle, _
                           posterCommon.location.defaultInputTitle)
        stringRegisterImpl(ds, "posterStringRegister_defaultValue", _
                           posterCommon.defaultValueVar, ds.defaultValue, posterCommon.defaultValue)
    End Sub

    Public Sub setData(ByVal ds As datasource, _
                       Optional ByRef inputId As String = Nothing)
        assert(Not ds Is Nothing, "ds is nothing.")

        If Not ds.page Is Nothing AndAlso Not ds.page.inlineScript() Is Nothing Then
            stringRegister(ds)
        End If

        inputId = inputIdBase + rndenchar() + rndenchar()
        Dim container As div = Nothing
        container = New div()
        container.class = containerClassName
        addchild(container)

        Dim textarea As textarea = Nothing
        textarea = New textarea()
        textarea.name = ds.inputName
        textarea.class = inputClassName
        textarea.id = inputId
        container.addchild(textarea)

        Dim buttons As div = Nothing
        buttons = New div()
        buttons.class = buttonsClassName
        buttons.addchild(createButton(ds.imageImage, ds.imageText, posterCommon.image.defaultText, _
                                      ds, posterCommon.image.inputTitleVar, _
                                      posterCommon.image.startTag, posterCommon.image.endTag, inputId))
        buttons.addchild(createButton(ds.urlImage, ds.urlText, posterCommon.url.defaultText, _
                                      ds, posterCommon.url.inputTitleVar, _
                                      posterCommon.url.startTag, posterCommon.url.endTag, inputId))
        buttons.addchild(createButton(ds.mediaImage, ds.mediaText, posterCommon.media.defaultText, _
                                      ds, posterCommon.media.inputTitleVar, _
                                      posterCommon.media.startTag, posterCommon.media.endTag, inputId))
        buttons.addchild(createButton(ds.flashImage, ds.flashText, posterCommon.flash.defaultText, _
                                      ds, posterCommon.flash.inputTitleVar, _
                                      posterCommon.flash.startTag, posterCommon.flash.endTag, inputId))
        buttons.addchild(createButton(ds.locationImage, ds.locationText, posterCommon.location.defaultText, _
                                      ds, posterCommon.location.inputTitleVar, _
                                      posterCommon.location.startTag, posterCommon.location.endTag, inputId, False))
        If Not isemptystring(ds.previewUrl) Then
            Dim submit As button = Nothing
            submit = New button()
            submit.onclick = previewInvoke(ds, inputId)
            setButtonAppearance(submit, ds.previewImage, ds.previewText, posterCommon.preview.defaultText)
            buttons.addchild(submit)
        End If
        container.addchild(buttons)

        Dim span As span = Nothing
        span = New span()
        span.class = supportedTagsClassName
        span.text = ifoper(isemptystring(ds.supportedTagsText), _
                           posterCommon.defaultSupportedTagsText, ds.supportedTagsText) + character.blank
        span.text += character.leftBrace + _
                     ifoper(isemptystring(ds.imageName), posterCommon.image.defaultName, ds.imageName) + _
                     character.blank + posterCommon.image.startTag + _
                     character.blank + posterCommon.image.endTag + _
                     character.rightBrace + character.blank
        span.text += character.leftBrace + _
                     ifoper(isemptystring(ds.urlName), posterCommon.url.defaultName, ds.urlName) + _
                     character.blank + posterCommon.url.startTag + _
                     character.blank + posterCommon.url.endTag + _
                     character.rightBrace + character.blank
        span.text += character.leftBrace + _
                     ifoper(isemptystring(ds.mediaName), posterCommon.media.defaultName, ds.mediaName) + _
                     character.blank + posterCommon.media.startTag + _
                     character.blank + posterCommon.media.endTag + _
                     character.rightBrace + character.blank
        span.text += character.leftBrace + _
                     ifoper(isemptystring(ds.flashName), posterCommon.flash.defaultName, ds.flashName) + _
                     character.blank + posterCommon.flash.startTag + _
                     character.blank + posterCommon.flash.endTag + _
                     character.rightBrace + character.blank
        span.text += character.leftBrace + _
                     ifoper(isemptystring(ds.locationName), posterCommon.location.defaultName, ds.locationName) + _
                     character.blank + posterCommon.location.startTag + _
                     character.blank + posterCommon.location.endTag + _
                     character.rightBrace + character.blank

        container.addchild(span)
    End Sub

    Public Sub New(Optional ByVal buff As Stream = Nothing)
        MyBase.New(buff)
    End Sub

    Public Sub New(ByVal ds As datasource, Optional ByVal buff As Stream = Nothing)
        Me.New(buff)
        setData(ds)
    End Sub
End Class

Public Class posterViewer
    Inherits div

    Public Const preClassName As String = "wc_pv"
    Public Const imageClassName As String = "i"
    Public Const urlClassName As String = "u"
    Public Const mediaClassName As String = "m"
    Public Const flashClassName As String = "f"
    Public Const locationClassName As String = "l"
    Public Const promoteClassName As String = "p"
    Public Const promotePreClassName As String = "pwc_pv"

    Public Class datasource
        Public page As xhtmlpage = Nothing
        Public text As String = Nothing
        Public isIEUserAgent As Boolean = False
        Public maxlength As Int64 = maxInt64
        Public promoteMultimediaContent As Boolean = False
        Public locationErrorText As String = Nothing
    End Class

    Private Shared Function generateControl(ByVal ds As datasource, ByVal startTag As String, _
                                            ByVal endTag As String, ByVal s As String, _
                                            ByVal asPromoted As Boolean) As String
        Dim c As xhtmlControl = Nothing
        If strsame(startTag, posterCommon.image.startTag, False) AndAlso _
           strsame(endTag, posterCommon.image.endTag, False) Then
            c = New img()
            With convertor.cast(Of img)(c)
                .src = s
                .class = imageClassName
            End With
        ElseIf strsame(startTag, posterCommon.url.startTag, False) AndAlso _
               strsame(endTag, posterCommon.url.endTag, False) Then
            c = New a()
            With convertor.cast(Of a)(c)
                .href = s
                .text = s
                .class = urlClassName
            End With
        ElseIf strsame(startTag, posterCommon.media.startTag, False) AndAlso _
               strsame(endTag, posterCommon.media.endTag, False) Then
            c = New mediaplayer()
            Dim mds As mediaplayer.datasource = Nothing
            mds = New mediaplayer.datasource()
            mds.link = s
            mds.isIEUserAgent = ds.isIEUserAgent
            With convertor.cast(Of mediaplayer)(c)
                .setData(mds)
                .class = mediaClassName
            End With
        ElseIf strsame(startTag, posterCommon.flash.startTag, False) AndAlso _
               strsame(endTag, posterCommon.flash.endTag, False) Then
            c = New flashplayer()
            Dim fds As flashplayer.datasource = Nothing
            fds = New flashplayer.datasource()
            fds.link = s
            With convertor.cast(Of flashplayer)(c)
                .setData(fds)
                .class = flashClassName
            End With
        ElseIf strsame(startTag, posterCommon.location.startTag, False) AndAlso _
               strsame(endTag, posterCommon.location.endTag, False) Then
            c = New googlemap(s, ds.locationErrorText)
            c.class = locationClassName
        Else
            Return emptyString
        End If

        If asPromoted Then
            c.class += character.blank + promoteClassName
        End If

        'since we are in a pre, so should always compress
        Return c.ToString(True)
    End Function

    'directly replace the string, so save time to render
    Private Shared Sub replace(ByVal ds As datasource, ByRef s As String, _
                               ByVal startTag As String, ByVal endTag As String, _
                               ByRef promoted As Boolean, ByVal asMultimediaContent As Boolean)
        assert(Not ds Is Nothing, "ds is nothing.")
        assert(Not isemptystring(s), "s is an empty string.")
        Dim startTagLen As Int32
        Dim endTagLen As Int32
        startTagLen = strlen(startTag)
        endTagLen = strlen(endTag)
        Dim startTagIndex As Int32 = 0
        Dim endTagIndex As Int32
        Do
            startTagIndex = s.IndexOf(startTag, startTagIndex)
            If startTagIndex <> npos Then
                endTagIndex = s.IndexOf(endTag, startTagIndex + startTagLen)

                If endTagIndex <> npos Then
                    Dim s2 As String = Nothing
                    s2 = htmlUtils.unescape(strmid(s, startTagIndex + startTagLen, _
                                                   endTagIndex - startTagIndex - startTagLen))
                    s = s.Remove(startTagIndex, endTagIndex + endTagLen - startTagIndex)
                    If ds.promoteMultimediaContent AndAlso asMultimediaContent AndAlso Not promoted Then
                        s = generateControl(ds, startTag, endTag, s2, True) + s
                        promoted = True
                    Else
                        s = s.Insert(startTagIndex, generateControl(ds, startTag, endTag, s2, False))
                    End If
                End If

                startTagIndex += startTagLen
            End If
        Loop Until startTagIndex = npos
    End Sub

    Public Sub setData(ByVal ds As datasource)
        assert(Not ds Is Nothing, "ds is nothing.")
        If Not isemptystring(ds.text) Then
            Dim container As pre = Nothing
            container = New autowrappre(ds.page)
            container.class = preClassName
            addchild(container)

            Dim s As String = Nothing
            copy(s, ds.text)

            htmlUtils.escape(s)
            Dim promoted As Boolean = False
            replace(ds, s, posterCommon.image.startTag, posterCommon.image.endTag, promoted, True)
            replace(ds, s, posterCommon.url.startTag, posterCommon.url.endTag, promoted, False)
            replace(ds, s, posterCommon.media.startTag, posterCommon.media.endTag, promoted, True)
            replace(ds, s, posterCommon.flash.startTag, posterCommon.flash.endTag, promoted, True)
            replace(ds, s, posterCommon.location.startTag, posterCommon.location.endTag, promoted, True)
            If promoted Then
                container.class += character.blank + promotePreClassName
            End If
            Dim xmltext As xmltext = Nothing
            xmltext = New xmltext(textEncodingEnum.none, output())
            xmltext.text = utils.truncate(s, ds.maxlength)
            container.addchild(xmltext)
        End If
    End Sub

    Public Sub New(ByVal ds As datasource, Optional ByVal buff As Stream = Nothing)
        Me.New(buff)
        setData(ds)
    End Sub

    Public Sub New(Optional ByVal buff As Stream = Nothing)
        MyBase.New(buff)
    End Sub
End Class